package bean.jugador;

import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;

import bean.Logro;
import bean.Muerte;
import bean.juego.Juego;
import logic.Filtro;

public class Jugador {

	private final DatosJugador datos;
	private final DatosJugadorFun datosF;
	private final Map<Logro, Integer> logros;
	private final AccionesBandera accionesBandera;
	private final List<Muerte> muertesHechas;
	private final List<Muerte> muertesRecibidas;
	private final List<Juego> historicoJuegos;
	private final List<Integer> historicoPuntos;
	private int puntosTotal;
	private int partidos;
	private int partidosGanados;
	private int tiempoJugado;

	public Jugador(DatosJugador datos, DatosJugadorFun datosF) {
		super();
		this.datos = datos;
		this.datosF = datosF;
		this.muertesHechas = new ArrayList<Muerte>();
		this.muertesRecibidas = new ArrayList<Muerte>();
		this.logros = new EnumMap<Logro, Integer>(Logro.class);
		this.accionesBandera = new AccionesBandera();
		this.puntosTotal = 0;
		this.partidos = 0;
		this.historicoJuegos = new ArrayList<Juego>();
		this.historicoPuntos = new ArrayList<Integer>();
		this.tiempoJugado = 0;
		this.partidosGanados = 0;
	}

	public Jugador(String nombre, DatosJugadorFun datosF) {
		this(new DatosJugador(nombre), datosF);
		this.datos.getApodos().add(nombre);
	}

	public DatosJugador getDatos() {
		return this.datos;
	}

	public Map<Logro, Integer> getLogros() {
		return this.logros;
	}

	public AccionesBandera getAccionesBandera() {
		return this.accionesBandera;
	}

	public List<Muerte> getMuertesHechas() {
		return this.muertesHechas;
	}

	public List<Muerte> getMuertesRecibidas() {
		return this.muertesRecibidas;
	}

	public DatosJugadorFun getDatosF() {
		return this.datosF;
	}

	public void sumarLogro(Logro logro) {
		if (this.logros.containsKey(logro)) {
			this.logros.put(logro, this.logros.get(logro) + 1);
		} else {
			this.logros.put(logro, 1);
		}
	}

	@Override
	public String toString() {
		return this.datos.getNombre();
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.datos == null) ? 0 : this.datos.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}
		if (this.getClass() != obj.getClass()) {
			return false;
		}
		Jugador other = (Jugador) obj;
		if (this.datos == null) {
			if (other.datos != null) {
				return false;
			}
		} else if (!this.datos.equals(other.datos)) {
			return false;
		}
		return true;
	}

	public int getPuntosTotal() {
		return this.puntosTotal;
	}

	public void agregarJuego(Juego juego) {
		Integer puntos = juego.getMapaPuntosJugador().get(this);
		this.puntosTotal += puntos;
		this.historicoJuegos.add(juego);
		this.historicoPuntos.add(puntos);
		this.tiempoJugado+=juego.getTiempoEnSegundos();
		this.partidos++;

		if (juego.esGanador(this)) {
			this.partidosGanados++;
		}
	}

	public int getPartidos() {
		return this.partidos;
	}

	public float getPromedioPuntos() {
		if (this.partidos == 0) {
			return 0;
		} else {
			return (float) this.puntosTotal / this.partidos;
		}
	}

	public float getPromedioMuertesHechas() {
		if (this.partidos == 0) {
			return 0;
		} else {
			return (float) this.muertesHechas.size() / this.partidos;
		}
	}

	public float getPromedioMuertesRecibidas() {
		if (this.partidos == 0) {
			return 0;
		} else {
			return (float) this.muertesRecibidas.size() / this.partidos;
		}
	}

	public float getCapturasPorPartido() {
		if (this.partidos == 0) {
			return 0;
		} else {
			return (float) this.accionesBandera.getBanderasCapturadas() / this.partidos;
		}
	}

	public List<Juego> getHistoricoJuegos() {
		return this.historicoJuegos;
	}

	public List<Integer> getHistoricoPuntos() {
		return this.historicoPuntos;
	}

	public int getTiempoJugado() {
		return this.tiempoJugado;
	}

	public int getPartidosGanados() {
		return this.partidosGanados;
	}

	public double getEfectividad() {
        if (this.getPartidos() == 0) {
            return 0;
        }
		return (double) this.getPartidosGanados() / this.getPartidos();
	}

    public double getPuntosPorMinuto() {
        if (this.getTiempoJugado() == 0) {
            return 0;
        }
		return (double) 60 * this.getPuntosTotal() / this.getTiempoJugado();
	}


    public double getDeathsKillsRatio() {
        if (this.getMuertesRecibidas().isEmpty()) {
            return 0;
        }
		return (double) this.getMuertesHechas().size() / this.getMuertesRecibidas().size();
	}

    public double getVecesMVPporPartido() {
        if (this.getPartidos() == 0) {
            return 0;
        }
		return Filtro.getHistoricoMVP().get(this) / (double)this.getPartidos();
	}

}
